﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using MyHelper;
using System.Linq.Expressions;
using System.Text;
using System.Web.UI;
using System.ComponentModel;

namespace MyHelper
{
    public static class SomeControl
    {
        #region SubmitButton
        public static string SubmitButton(this HtmlHelper htmlHelper, string imageLink, string value, string altText)
        {
            return string.Format("<input type='image' src='{0}' value='{1}' alt='{2}' />", imageLink, value, altText);
        }
        #endregion;

        #region ImageActionLink
        public static string ImageActionLink(this HtmlHelper helper, string imagePath, string actionName, string controllerName, object routeValues, object imageAttributes, object linkAttributes)  
         {  
            var urlHelper = new UrlHelper(helper.ViewContext.RequestContext, helper.RouteCollection);  
            var anchortagBuilder = new TagBuilder("a");  
            anchortagBuilder.MergeAttributes(new RouteValueDictionary(linkAttributes));  
            anchortagBuilder.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));  
          
            var imageTagBuilder = new TagBuilder("img");  
            imageTagBuilder.MergeAttributes(new RouteValueDictionary(imageAttributes));  
            imageTagBuilder.MergeAttribute("src", imagePath);  
            anchortagBuilder.InnerHtml = imageTagBuilder.ToString(TagRenderMode.SelfClosing);  

            return anchortagBuilder.ToString(TagRenderMode.Normal);
         }
        #endregion;

        #region DateTimePicker

        public static string DatePicker(this HtmlHelper helper, string name)
        {
            return helper.DatePicker(name, null);
        }

        public static string DatePicker(this HtmlHelper helper, string name, string imageUrl)
        {
            return helper.DatePicker(name, imageUrl, null);
        }

        public static string DatePicker(this HtmlHelper helper, string name, object date)
        {
            return helper.DatePicker(name, "/Content/images/calendar.gif", date);
        }

        public static string DatePicker(this HtmlHelper helper, string name, string imageUrl, object date)
        {
            StringBuilder html = new StringBuilder();

            // Build our base input element
            html.Append("<input type=\"text\" id=\"" + name + "\" name=\"" + name + "\"");

            // Model Binding Support
            if (date != null)
            {
                string dateValue = String.Empty;

                if (date is DateTime? && ((DateTime)date) != DateTime.MinValue)
                    dateValue = ((DateTime)date).ToShortDateString();
                else if (date is DateTime && (DateTime)date != DateTime.MinValue)
                    dateValue = ((DateTime)date).ToShortDateString();
                else if (date is string)
                    dateValue = (string)date;

                html.Append(" value=\"" + dateValue + "\"");
            }

            // We're hard-coding the width here, a better option would be to pass in html attributes and reflect through them
            // here ( default to 75px width if no style attributes )
            html.Append(" style=\"width: 75px;\" />");

            // Now we call the datepicker function, passing in our options.  Again, a future enhancement would be to
            // pass in date options as a list of attributes ( min dates, day/month/year formats, etc. )
            html.Append("<script type=\"text/javascript\">$(document).ready(function() { $('#" + name + "').datepicker({ showOn: 'button', buttonImage: '" + imageUrl + "', duration: 0 }); });</script>");

            return html.ToString();
        }

        #endregion;

        #region SubmitConfirm

        public static string SubmitConfirm(this HtmlHelper helper,
           string buttonText, string alertMessage)
        {
            return String.Format(
            "<input type=\"submit\" value=\"{0}\" onClick=\"return confirm('{1}');\" />",
            buttonText, alertMessage);
        }

        #endregion

        #region RadioButtonList

        public static void ShowRadioButtonList<T>(this ViewPage page, IList<T> list, string name, Expression<Func<T, object>> valueProperty, Expression<Func<T, object>> displayProperty, System.Web.UI.WebControls.Orientation orientation)  
        { 
            page.ShowRadioButtonList(list, name, valueProperty, displayProperty, "3", orientation); 
        }  
        
        public static void ShowRadioButtonList<T>(this ViewPage page, IList<T> list, string name, Expression<Func<T, object>> valueProperty, Expression<Func<T, object>> displayProperty, string selectedValue, System.Web.UI.WebControls.Orientation orientation)  
        {  
            HtmlTextWriter writer = new HtmlTextWriter(page.Response.Output);  
            if (writer != null) 
            {  
                Func<T, object> valueGetter = valueProperty.Compile();  
                Func<T, object> displayStringGetter = displayProperty.Compile(); 
                for (int i = 0; i < list.Count; i++)  
                {  
                    T row = list[i]; 
                    string value = valueGetter(row).ToString(); 
                    writer.AddAttribute(HtmlTextWriterAttribute.Type, "radio"); 
                    writer.AddAttribute(HtmlTextWriterAttribute.Id, name + "_" + i); 
                    writer.AddAttribute(HtmlTextWriterAttribute.Name, name, true);  
                    writer.AddAttribute(HtmlTextWriterAttribute.Value, value, true);  
                    if (value == selectedValue)  
                    {  
                        writer.AddAttribute(HtmlTextWriterAttribute.Checked,"checked");  
                    }  
                    writer.RenderBeginTag(HtmlTextWriterTag.Input);  
                    writer.Write(displayStringGetter(row));  
                    writer.RenderEndTag();  
                    if (orientation == System.Web.UI.WebControls.Orientation.Vertical)  
                    {  
                        writer.RenderBeginTag(HtmlTextWriterTag.Br); 
                        writer.RenderEndTag(); 
                    }  
                }  
            } 
        }

        #endregion

        #region DataListExtension

        public static DataList<T> DataList<T>(this HtmlHelper htmlHelper, IEnumerable<T> datasource) where T : class
        {
            return new DataList<T>(datasource, htmlHelper.ViewContext.HttpContext.Response.Output, htmlHelper.ViewContext);
        }

        public static DataListItem<T> Template<T>(this DataListItem<T> item, Action<T> action) where T : class
        {
            item.CustomRenderer = (context, dataItem) => action(dataItem);

            return item;
        }

        public static DataListItem<T> PartialView<T>(this DataListItem<T> item, string partialViewName) where T : class
        {
            item.CustomRenderer = (context, dataItem) =>
            {
                // var view = context.ViewEngines.TryLocatePartial(context.ViewContext, partialViewName);
                var view = context.ViewEngines.FindPartialView(context.ViewContext, partialViewName).View;
                var newViewData = new ViewDataDictionary<T>(dataItem);
                var newContext = new ViewContext(context.ViewContext, context.ViewContext.View, newViewData, context.ViewContext.TempData);
                view.Render(newContext, context.Writer);
            };

            return item;
        }

        public static DataList<T> Columns<T>(this DataList<T> dataList, int columns) where T : class
        {
            if (columns <= 0)
                throw new ArgumentException("# of columns must be positive");

            dataList.Columns = columns;

            return dataList;
        }

        public static DataListItem<T> ItemAttributes<T>(this DataListItem<T> dataListItem, object itemAttributes) where T : class
        {
            Dictionary<string, string> attributes = new Dictionary<string, string>();

            foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(itemAttributes))
            {
                attributes.Add(propertyDescriptor.Name, propertyDescriptor.GetValue(itemAttributes).ToString());
            }

            dataListItem.ItemAttributes(attributes);

            return dataListItem;
        }

        #endregion

    }
}
